

package cn.shengchao.examstar.account.acl.adapters.repositories;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.shengchao.examstar.account.acl.ports.repositories.IAccountRepository;
import cn.shengchao.examstar.account.domain.Account;
import cn.shengchao.examstar.account.domain.AccountPayLog;
import cn.shengchao.examstar.account.domain.AccountPayoutsLog;
import cn.shengchao.examstar.account.infrastructure.dao.AccountDao;
import cn.shengchao.examstar.account.infrastructure.dao.AccountPayLogDao;
import cn.shengchao.examstar.account.infrastructure.dao.AccountPayoutsLogDao;
import cn.shengchao.examstar.account.infrastructure.dao.po.TAccount;
import cn.shengchao.examstar.account.infrastructure.dao.po.TAccountPayLog;
import cn.shengchao.examstar.account.infrastructure.dao.po.TAccountPayoutsLog;
import cn.shengchao.examstar.account.infrastructure.dao.vo.AccountList;
import cn.shengchao.examstar.account.infrastructure.dao.vo.PayoutsList;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

@Repository
public class AccountRepository implements IAccountRepository {

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private AccountPayLogDao accountPayLogDao;

    @Autowired
    private AccountPayoutsLogDao accountPayoutsLogDao;

    @Override
    public Account of(Long accountId) {
        TAccount tAccount = accountDao.selectById(accountId);
        Account account = new Account();
        account.setId(tAccount.getId());
        account.setBalance(tAccount.getBalance());
        account.setFrozenBalance(tAccount.getFrozenBalance());
        account.setWithdrawBalance(tAccount.getWithdrawBalance());
        account.setPointsBalance(tAccount.getPointsBalance());
        account.setUserId(tAccount.getUserId());
        account.setOpenId(tAccount.getOpenId());
        account.setObjectId(tAccount.getObjectId());
        account.setObjectType(tAccount.getObjectType());
        return account;
    }

    @Override
    public void update(Account account) {
        TAccount tAccount = new TAccount();
        tAccount.setBalance(account.getBalance());
        tAccount.setId(account.getId());
        tAccount.setFrozenBalance(account.getFrozenBalance());
        tAccount.setPointsBalance(account.getPointsBalance());
        tAccount.setWithdrawBalance(account.getWithdrawBalance());
        tAccount.setUserId(account.getUserId());
        tAccount.setOpenId(account.getOpenId());
        tAccount.setObjectId(account.getObjectId());
        tAccount.setObjectType(account.getObjectType());
        accountDao.updateById(tAccount);

    }

    @Override
    public void saveAccountPayLog(AccountPayLog accountPayLog) {
        TAccountPayLog tAccountPayLog = new TAccountPayLog();
        tAccountPayLog.setAmount(accountPayLog.getAmount());
        tAccountPayLog.setType(accountPayLog.getType());
        tAccountPayLog.setTime(accountPayLog.getTime());
        tAccountPayLog.setPayNumber(accountPayLog.getPayNumber());
        tAccountPayLog.setAccountId(accountPayLog.getAccountId());
        tAccountPayLog.setUserId(accountPayLog.getUserId());
        tAccountPayLog.setRemark(accountPayLog.getRemark());
        accountPayLogDao.insert(tAccountPayLog);
    }

    @Override
    public Optional<Account> ofByUid(Long uid) {
        TAccount tAccount = accountDao.selectOne(new LambdaQueryWrapper<TAccount>().eq(TAccount::getUserId, uid));
        if (tAccount != null) {
            Account account = new Account();
            account.setId(tAccount.getId());
            account.setBalance(tAccount.getBalance());
            account.setFrozenBalance(tAccount.getFrozenBalance());
            account.setWithdrawBalance(tAccount.getWithdrawBalance());
            account.setPointsBalance(tAccount.getPointsBalance());
            account.setUserId(tAccount.getUserId());
            account.setOpenId(tAccount.getOpenId());
            return Optional.of(account);
        }
        return Optional.empty();
    }

    @Override
    public BigDecimal getYesterdayIncome(Long accountId) {
        List<TAccountPayLog> accountPayLogs = accountPayLogDao.selectList(new LambdaQueryWrapper<TAccountPayLog>()
            .eq(TAccountPayLog::getAccountId, accountId));
        //筛选昨日的订单
        DateTime beginYesterday = DateUtil.beginOfDay(DateUtil.yesterday());
        double amount = accountPayLogs.stream()
            .filter(accountPayLog -> DateUtil.isSameTime(accountPayLog.getTime(), beginYesterday) && ("1"
                .equals(accountPayLog.getType())))
            .mapToDouble(item -> item.getAmount().doubleValue())
            .sum();
        return BigDecimal.valueOf(amount);
    }

    @Override
    public void saveAccountPayoutsLog(AccountPayoutsLog accountPayoutsLog) {
        TAccountPayoutsLog tAccountPayoutsLog = new TAccountPayoutsLog();
        tAccountPayoutsLog.setAccountId(accountPayoutsLog.getAccountId());
        tAccountPayoutsLog.setUserId(accountPayoutsLog.getUserId());
        tAccountPayoutsLog.setOpenId(accountPayoutsLog.getOpenId());
        tAccountPayoutsLog.setPayoutsAmount(accountPayoutsLog.getPayoutsAmount());
        tAccountPayoutsLog.setStatus(accountPayoutsLog.getStatus());
        tAccountPayoutsLog.setFiledTime(accountPayoutsLog.getFiledTime());
        tAccountPayoutsLog.setProcessingTime(accountPayoutsLog.getProcessingTime());
        tAccountPayoutsLog.setBackCardId(accountPayoutsLog.getBackCardId());
        tAccountPayoutsLog.setCardNo(accountPayoutsLog.getCardNo());
        tAccountPayoutsLog.setBankOfDeposit(accountPayoutsLog.getBankOfDeposit());
        tAccountPayoutsLog.setBalance(accountPayoutsLog.getBalance());
        accountPayoutsLogDao.insert(tAccountPayoutsLog);
    }

    @Override
    public List<AccountList> accountLists(Long userId) {
        return accountDao.accountLists(userId);
    }

    @Override
    public List<PayoutsList> payoutsLog(Long userId) {
        return accountPayoutsLogDao.selectList(new LambdaQueryWrapper<TAccountPayoutsLog>()
            .eq(TAccountPayoutsLog::getUserId, userId)).stream().map(item -> {
                PayoutsList payoutsList = new PayoutsList();
                payoutsList.setId(item.getId());
                payoutsList.setCreateTime(item.getFiledTime());
                payoutsList.setPayMoney(item.getPayoutsAmount());
                payoutsList.setBalance(item.getBalance());
                return payoutsList;
            }).toList();
    }
}
